package com.manager.core.web.controller;

import java.beans.PropertyEditorSupport;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.manager.commons.utils.ClassUtil;
import com.manager.commons.utils.StringUtil;
import com.manager.core.web.json.AjaxJson;
import org.apache.commons.text.StringEscapeUtils;
import org.slf4j.Logger;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.servlet.ModelAndView;

import com.manager.commons.Constant;
import com.manager.commons.log.LogFactory;
import com.manager.commons.utils.DateUtil;
import com.manager.commons.base.SessionUser;

/**
 * 控制器基础类
 *
 * @author H
 */
public abstract class BaseController<T> {

    /**
     * 日志对象
     */
    protected Logger logger = LogFactory.getLogger(getClass());
    @Resource
    public HttpServletRequest request;
    @Resource
    public HttpServletResponse response;

    public abstract T getModel();

    /**
     * 初始化数据绑定 1. 将所有传递进来的String进行HTML编码，防止XSS攻击 2. 将字段中Date类型转换为String类型
     *
     * @param binder
     */
    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        // String类型转换，将所有传递进来的String进行HTML编码，防止XSS攻击
        binder.registerCustomEditor(String.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) {
                setValue(text == null ? null : StringEscapeUtils.escapeHtml4(text.trim()));
            }

            @Override
            public String getAsText() {
                Object value = getValue();
                return value != null ? value.toString() : "";
            }
        });
        // Date 类型转换
        binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) {
                try {
                    setValue(DateUtil.parseDate(text));
                } catch (ParseException e) {
                    logger.error(e.getMessage(), e);
                }
            }
        });

    }

    /**
     * 根据参数名称获取参数值
     *
     * @param key
     * @return
     */
    protected String getKeyParam(String key) {
        return request.getParameter(key);
    }

    /**
     * 获取id参数
     *
     * @return
     */
    protected String getIdParam() {
        return getKeyParam("_id");
    }

    protected T getParamsModel() {
        Map<String, Object> maps = getParams();
        return JSONObject.parseObject(JSONObject.toJSONString(maps), entityClass, Feature.OrderedField);
    }

    /**
     * 获取参数
     *
     * @return
     */
    protected Map<String, Object> getParams() {
        Map<String, String[]> entrys = request.getParameterMap();
        Map<String, Object> maps = new HashMap<>();
        int page = 0, rows = 0;
        for (Map.Entry<String, String[]> entry : entrys.entrySet()) {
            String[] strs = entry.getValue();
            String key = entry.getKey();
            if (strs != null && strs.length > 0) {
                if (strs.length == 1) {
                    String value = strs[0].trim();
                    if (StringUtil.isNotEmpty(value)) {
                        if (key.equals("_ids")) {
                            String[] __ids = strs[0].split(",");
                            maps.put("_ids", __ids);
                        } else if (key.equals("page")) {
                            page = Integer.parseInt(value);
                        } else if (key.equals("limit")) {
                            rows = Integer.parseInt(value);
                        } else {
                            maps.put(key, strs[0]);
                        }
                    }
                } else {
                    maps.put(key, strs);
                }
            }
        }
        //添加分页参数
        if (page > 0 && rows > 0) {
            maps.put("page", ((page - 1) * rows));
            maps.put("rows", rows);
        }
        return maps;
    }


    /**
     * 获取session
     *
     * @return
     */
    public HttpSession getSession() {
        HttpSession session = request.getSession();
        return session;
    }


    /**
     * 获取session中用户
     *
     * @return
     */
    protected SessionUser getUserSession() {
        HttpSession session = request.getSession();
        Object user = (session == null) ? null : session.getAttribute(Constant.LOGIN_USER_SESSION);
        return (SessionUser) user;
    }

    /**
     * 获取ModelAndView对象
     *
     * @param path
     * @return
     */
    protected ModelAndView getModelAndView(String path) {
        return new ModelAndView(path);
    }

    public AjaxJson success(Object data, String msg) {
        return new AjaxJson(1, msg, data);
    }

    public AjaxJson success(Object data) {
        return new AjaxJson(1, "成功", data);
    }

    public AjaxJson error(String msg) {
        return new AjaxJson(0, msg);
    }

    public AjaxJson result(int code, String msg) {
        String m = msg;
        if (StringUtil.isEmpty(m)) {
            if (code > 0) {
                m = "操作成功";
            } else {
                m = "操作失败";
            }
        }
        return new AjaxJson(code, m);
    }

    // 程序运行时，当前类将作为基类被继承，通过反射工具类getGenericClassTpye，得到此时泛型 所指定的实际型参数类型
    protected Class<T> entityClass = ClassUtil.getGenericClassTpye(this
            .getClass());
}